//
//  JXCalendarView.m
//  TestCollectionView
//
//  Created by Lemon on 2019/4/20.
//  Copyright © 2019 sunshinfight@163.com. All rights reserved.
//

#import "JXCalendarView.h"
#import "JXCalendarLayout.h"
#import "JXCalendarMonthHeaderView.h"
#import "JXCalendarItemCell.h"
#import "JXCalendarYearHeaderView.h"
#import "JXWeekdayIndicatorView.h"

#define kCalendarItemCellKey  @"calendarCell"
#define kCalendarMonthHeaderKey  @"calendarMonthHeader"
#define kCalendarYearHeaderKey @"kCalendarYearHeaderKey"

@interface JXCalendarView () <UICollectionViewDataSource, UICollectionViewDelegate>
@property (nonatomic, strong) JXCalendarLayout *layout;
@property (nonatomic, strong) JXWeekdayIndicatorView *weekdayView;
@end

@implementation JXCalendarView
@dynamic sectionInsets;
@dynamic monthHeaderSectionInsets;
@dynamic yearHeaderSectionInsets;
@dynamic minimumInteritemSpacing;
@dynamic minimumLineSpacing;
@dynamic startYear;
@dynamic endYear;

// MARK: - life cycle
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        JXCalendarLayout *layout = [JXCalendarLayout new];
        _layout = layout;
        _gridView = [[UICollectionView alloc] initWithFrame:frame collectionViewLayout:layout];
        _weekdayView = [JXWeekdayIndicatorView new];
        [self configUI];
        [self registerCollectionDateSourceAndDelegate];
    }
    return self;
}

- (instancetype)init
{
    self = [self initWithFrame:CGRectZero];
    return self;
}

// MARK: - UI configaration
- (void) configUI
{
    self.backgroundColor = UIColor.whiteColor;
    
    self.gridView.backgroundColor = UIColor.whiteColor;
    self.gridView.allowsMultipleSelection = YES;
    self.gridView.showsVerticalScrollIndicator = NO;
    
    self.weekdayView.insets = self.sectionInsets;
    self.weekdayView.minimumInteritemSpacing = self.minimumInteritemSpacing;
    
    [self addSubview:self.gridView];
    [self addSubview:self.weekdayView];
}

- (void)layoutSubviews
{
    self.gridView.frame = CGRectMake(0, 30, self.bounds.size.width, self.bounds.size.height-30);
    self.weekdayView.frame = CGRectMake(0, 0, self.frame.size.width, 50);
}

- (void)registerCollectionDateSourceAndDelegate
{
    [self.gridView registerClass:[JXCalendarMonthHeaderView class] forSupplementaryViewOfKind:JXColletionKindMonth withReuseIdentifier:kCalendarMonthHeaderKey];
    [self.gridView registerClass:[JXCalendarItemCell class] forCellWithReuseIdentifier:kCalendarItemCellKey];
    [self.gridView registerClass:[JXCalendarYearHeaderView class] forSupplementaryViewOfKind:JXColletionKindYear withReuseIdentifier:kCalendarYearHeaderKey];
    self.gridView.dataSource = self;
    self.gridView.delegate = self;
}

// MARK: - synthetize
- (UIEdgeInsets)sectionInsets
{
    return _layout.sectionInsets;
}

- (void)setSectionInsets:(UIEdgeInsets)sectionInsets
{
    _layout.sectionInsets = sectionInsets;
    _weekdayView.insets = sectionInsets;
}

- (UIEdgeInsets)monthHeaderSectionInsets
{
    return _layout.monthHeaderInsets;
}

- (void)setMonthHeaderSectionInsets:(UIEdgeInsets)monthHeaderSectionInsets
{
    _layout.monthHeaderInsets = monthHeaderSectionInsets;
}

- (UIEdgeInsets)yearHeaderSectionInsets
{
    return _layout.yearHeaderInsets;
}

- (void)setYearHeaderSectionInsets:(UIEdgeInsets)yearHeaderSectionInsets
{
    _layout.yearHeaderInsets = yearHeaderSectionInsets;
}

- (CGFloat)minimumLineSpacing
{
    return _layout.minimumLineSpacing;
}

- (void)setMinimumLineSpacing:(CGFloat)minimumLineSpacing
{
    _layout.minimumLineSpacing = minimumLineSpacing;
}

- (CGFloat)minimumInteritemSpacing
{
    return _layout.minimumInteritemSpacing;
}

- (void)setMinimumInteritemSpacing:(CGFloat)minimumInteritemSpacing
{
    _layout.minimumInteritemSpacing = minimumInteritemSpacing;
    _weekdayView.minimumInteritemSpacing = minimumInteritemSpacing;
}

- (NSInteger)startYear
{
    return _layout.startYear;
}

- (void)setStartYear:(NSInteger)startYear
{
    _layout.startYear = (int32_t)startYear;
}

- (NSInteger)endYear
{
    return _layout.endYear;
}

- (void)setEndYear:(NSInteger)endYear
{
    _layout.endYear = (int32_t)endYear;
}

// MARK: - collection view date source
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return self.layout.dateDataSource.count;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.layout.dateDataSource[section].count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    JXCalendarItemCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCalendarItemCellKey forIndexPath:indexPath];
    JXCalendarModel *model = self.layout.dateDataSource[indexPath.section][indexPath.row];
    [cell configCellWithModel:model];
    return cell;
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    
    if ([kind isEqualToString:JXColletionKindYear]) {
        JXCalendarYearHeaderView *header = [collectionView dequeueReusableSupplementaryViewOfKind:JXColletionKindYear withReuseIdentifier:kCalendarYearHeaderKey forIndexPath:indexPath];
        JXCalendarModel *model = self.layout.dateDataSource[indexPath.section * 12][0];
        [header configUIWithModel:model];
        return header;
    } else {
        JXCalendarMonthHeaderView *header = [collectionView dequeueReusableSupplementaryViewOfKind:JXColletionKindMonth withReuseIdentifier:kCalendarMonthHeaderKey forIndexPath:indexPath];
        JXCalendarModel *model = self.layout.dateDataSource[indexPath.section][0];
//        header.dateLabel.text = [NSString stringWithFormat:@"%d月", model.month];
        [header configWithModel:model];
        return header;
    }
}

// MARK: - collection view delegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSMutableArray *selectedDates = [NSMutableArray new];
    
    NSArray<NSIndexPath* > *indexs = [collectionView indexPathsForSelectedItems];
    if (indexs.count == 2) {
        NSIndexPath *startIndex = indexs[0];
        NSIndexPath *endIndex = indexs[1];
        
        if (indexs[0].row < indexs[1].row) {
            startIndex = indexs[0];
            endIndex = indexs[1];

        } else if (indexs[0].row > indexs[1].row) {
            startIndex = indexs[1];
            endIndex = indexs[0];
        }
        if (indexs[0].section < indexs[1].section) {
            startIndex = indexs[0];
            endIndex = indexs[1];
        } else if (indexs[0].section > indexs[1].section) {
            startIndex = indexs[1];
            endIndex = indexs[0];
        }
        
        __weak typeof(self) wSelf = self;
        [self selectItemsWithStartIndex:startIndex endIndex:endIndex enumeratedBlock:^(NSIndexPath *selectedIndexPath) {
            [wSelf selectItemAndChangeModelWithIndexPath:selectedIndexPath];
            JXCalendarModel *model = self.layout.dateDataSource[selectedIndexPath.section][selectedIndexPath.row];
            [selectedDates addObject: model];
        }];
    } else {
        [self selectItemAndChangeModelWithIndexPath:indexPath];
        JXCalendarModel *model = self.layout.dateDataSource[indexPath.section][indexPath.row];
        [selectedDates addObject:model];
    }
    
    [selectedDates removeObjectIdenticalTo:NSNull.null];
    
    // delegate
    if (self.delegate) {
        if ([self.delegate respondsToSelector:@selector(jxCalendarViewDidSelectedDates:)]) {
            [self.delegate jxCalendarViewDidSelectedDates:[selectedDates copy]];
        }
    }
}

- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *indexs = [collectionView indexPathsForSelectedItems];
    if (indexs.count >= 2) {
        for (NSIndexPath *index in indexs) {
            if ([indexPath isEqual: index]) {
                [collectionView.delegate collectionView:collectionView didSelectItemAtIndexPath:index];
                continue;
            } else {
                [collectionView deselectItemAtIndexPath:index animated:true];
                JXCalendarModel *model = self.layout.dateDataSource[index.section][index.row];
                model.isSelected = NO;
            }
        }
    } else if (indexs.count == 1) {
//        [collectionView deselectItemAtIndexPath:indexPath animated:YES];
//        JXCalendarModel *model = self.layout.dateDataSource[indexPath.section][indexPath.row];
//        model.isSelected = NO;
    }
    return NO;
}

- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//    NSMutableArray *selectedDates = [NSMutableArray new];
    
    NSArray<NSIndexPath* > *indexs = [collectionView indexPathsForSelectedItems];
    if (indexs.count >= 2) {
        for (NSIndexPath *index in indexs) {
            [collectionView deselectItemAtIndexPath:index animated:true];
//            [selectedDates addObject:self.layout.dateDataSource[index.section][index.row]];
            JXCalendarModel *model = self.layout.dateDataSource[index.section][index.row];
            model.isSelected = NO;
        }
        
//        // delegate
//        if (self.delegate) {
//            if ([self.delegate respondsToSelector:@selector(jxCalendarViewDidSelectedDates:)]) {
//                [self.delegate jxCalendarViewDidSelectedDates:[selectedDates copy]];
//            }
//        }
        
//        if (self.delegate) {
//            if ([self.delegate respondsToSelector:@selector(jxCalendarViewDidClear)]) {
//                [self.delegate jxCalendarViewDidClear];
//            }
//        }
    }
    return YES;
}

- (void)selectItemsWithStartIndex: (NSIndexPath*)start endIndex:(NSIndexPath*)end enumeratedBlock:(void(^)(NSIndexPath*))block
{
    if (start.section == end.section) {
        for (int row = (int)start.row; row <= end.row; row++) {
            block([NSIndexPath indexPathForRow:row inSection:start.section]);
        }
    } else {
        NSArray<JXCalendarModel* > *sectionArray = self.layout.dateDataSource[start.section];
        for (int row = (int)start.row; row < sectionArray.count; row++) {
            block([NSIndexPath indexPathForRow:row inSection:start.section]);
        }
        
        for (int section = (int)start.section + 1; section < end.section; section++) {
            NSArray<JXCalendarModel* > *sectionArray = self.layout.dateDataSource[section];
            for (int row = 0; row < sectionArray.count; row++) {
                block([NSIndexPath indexPathForRow:row inSection:section]);
            }
        }
        
        for (int row = 0; row <= end.row; row++) {
            block([NSIndexPath indexPathForRow:row inSection:end.section]);
        }
    }
}

- (void)selectItemAndChangeModelWithIndexPath: (NSIndexPath*)indexPath
{
    JXCalendarModel *model = self.layout.dateDataSource[indexPath.section][indexPath.row];
    model.isSelected = YES;
    [self.gridView selectItemAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section] animated:true scrollPosition:UICollectionViewScrollPositionNone];
}

- (void)scrollToTodayWithScrollPosition: (UICollectionViewScrollPosition)position animated:(BOOL)animated
{
    NSDate *today = NSDate.date;
    NSInteger day;
    NSInteger month;
    NSInteger year;
    NSInteger era;
    [NSCalendar.currentCalendar getEra:&era year:&year month:&month day:&day fromDate:today];
    [self.gridView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:day-1 inSection:(month-1) + (year-self.layout.startYear)*12] atScrollPosition:position animated:animated];
}

- (void)deSelectedAllDatesAnimated:(BOOL)animated
{
    NSArray<NSIndexPath* > *indexs = [self.gridView indexPathsForSelectedItems];
    for (NSIndexPath *index in indexs) {
        [self.gridView deselectItemAtIndexPath:index animated:animated];
    }
}

@end
